package main;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import domain.parsers.ParseException;
import java.util.Iterator;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Parser;
import org.apache.commons.cli.PosixParser;

import domain.grammar.ExtendedGrammar;
import domain.grammar.ExtendedGrammarConflictException;
import domain.lexicalAnalyzerGenerator.CodeGenerationException;
import domain.lexicalAnalyzerGenerator.FunctionSet;
import domain.lexicalAnalyzerGenerator.InstructionException;
import domain.parsers.InputGrammarLL1Parser;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Options options = new Options();
		Option fileInPathOpt = new Option("in",true,"The path of the grammar specification file");
		Option fileOutPathOpt = new Option("out",true,"The path where the output code files will be created");
		fileInPathOpt.setRequired(true);
		
		options.addOption(fileInPathOpt);
		options.addOption(fileOutPathOpt);
		
		Parser parser = new PosixParser();

		try {
			CommandLine cmd = parser.parse(options, args);
			String inputFilePath = cmd.getOptionValue("in");
			File inputFile = new File(inputFilePath);
			InputGrammarLL1Parser igp = new InputGrammarLL1Parser();
			ExtendedGrammar eg = igp.parse(inputFile);
			FunctionSet fs = FunctionSet.create(eg);
			String generatedLexicalAnalyzer = fs.generateCode();
			String outFilePath;
			if(cmd.hasOption("out")){
				outFilePath = cmd.getOptionValue("out");
			}else{
				outFilePath = System.getProperty("user.dir");
			}

			File outFile = new File(outFilePath);
			if(!outFile.isDirectory()){
				
				outFile = new File(outFile.getParent()+File.separator+"Main.java");
			}else{
				String newOutFilePath = outFile.getAbsolutePath()+File.separator+"Main.java";
				outFile = new File(newOutFilePath);
			}
			if(!outFile.createNewFile()){
				throw new RuntimeException("Already exists a file named: "+outFile.getAbsolutePath() );
			}
			
			FileWriter outFileWriter = new FileWriter(outFile);
			outFileWriter.write(generatedLexicalAnalyzer);
			outFileWriter.flush();
			outFileWriter.close();
			
			System.out.println("The source file for the parser was successfully generated in:");
			System.out.println(outFile.getAbsolutePath());
		} catch (org.apache.commons.cli.ParseException e2) {
			System.err.println("Invalid options");
			System.err.println("===============");
			System.err.println("Usage: java -jar ParserCreator.jar -in <input-file-path> [OPTIONS]");
			System.err.println("Options:");
			Iterator itOp = options.getOptions().iterator();
			while(itOp.hasNext()){
				Option anOpt = (Option)itOp.next();
				if(!anOpt.isRequired()){
					System.err.println("-"+anOpt.getOpt()+"      "+anOpt.getDescription());
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InstructionException e) {
			e.printStackTrace();
		} catch (CodeGenerationException e) {
			e.printStackTrace();
		} catch (ExtendedGrammarConflictException e) {
			e.printStackTrace();
		}
	}
}
